package com.bitsfromspace.ubertorrent.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.StringTokenizer;

/**
 * Looks up the "external" IP address of this machine, by using IP Chicken's ip script: see:
 * www.ipchicken.com.
 * 
 * Author: chris.oudeman
 * Since: Jan 6, 2011
 */
public class IpUtils {

	/**
	 * Queries www.ipchicken.com to determine the external IP address for this machine.
	 * @return The queried IP address as a String, in x.x.x.x-form.
	 * @throws IOException when an I/O error occurred connecting to the ipchicken.com service,
	 * or when the returned IP address was not valid.
	 * @see #validateIp(String)
	 */
	public static String queryExternalIp() throws IOException {

		URL whatismyipUrl = null;
		BufferedReader reader = null;

		try {
			whatismyipUrl =
					new URL(
							"http://www.whatismyip.com/automation/n09230945.asp");
			reader =
					new BufferedReader(new InputStreamReader(
							whatismyipUrl.openStream()));
			String ip = reader.readLine();
			validateIp(ip);
			return ip;
		} finally {
			if (reader != null) {
				reader.close();
			}
		}
	}

	/**
	 * Validates wether paremeter <em>ip</em> is a valid IP address.
	 * @throws IOException when <em>ip> is NOT a valid ip address.
	 */
	public static void validateIp(String ip) throws IOException {

		StringTokenizer st = new StringTokenizer(ip, ".");
		if (st.countTokens() != 4) {
			throw new IOException("Invalid IP adress: " + ip);
		}
		while (st.hasMoreTokens()) {
			String nextSegment = st.nextToken();
			try {
				int ipSegment = Integer.parseInt(nextSegment);
				if (ipSegment < 0 || ipSegment > 255) {
					throw new IOException("Invalid IP address: " + ip);
				}
			} catch (NumberFormatException nfe) {
				throw new IOException("Invalid IP adress: " + ip);
			}
		}

	}

	/**
	 * Validates whether the port is valid.
	 */
	public static void validatePort(int port) throws IOException {

		if (port < 0 || port > Math.pow(2, 16)) {
			throw new IOException("Invalid IP port number: " + port);
		}

	}
}


